home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / bound.c < prev    next >
C/C++ Source or Header  |  1991-07-18  |  10KB  |  362 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : August 1985.
  7.  *    2nd revision : April 1988.
  8.  *
  9.  *    %W%    %G%
  10. */
  11. #include "fig.h"
  12. #include "object.h"
  13.  
  14. #define        Ninety_deg        M_PI_2
  15. #define        One_eighty_deg        M_PI
  16. #define        Two_seventy_deg        (M_PI + M_PI_2)
  17. #define        Three_sixty_deg        (M_PI + M_PI)
  18. #define        round(x)        ((int)((x) + .5))
  19. #define        half(z1 ,z2)        ((z1+z2)/2.0)
  20. /*#define        max(a, b)        (((a) > (b)) ? (a) : (b))*/
  21. /*#define        min(a, b)        (((a) < (b)) ? (a) : (b))*/
  22.  
  23. arc_bound(arc, xmin, ymin, xmax, ymax)
  24. F_arc    *arc;
  25. int    *xmin, *ymin, *xmax, *ymax;
  26. {
  27.     float    alpha, beta;
  28.     double    dx, dy, radius;
  29.     int    bx, by, sx, sy;
  30.  
  31.     dx = arc->point[0].x - arc->center.x;
  32.     dy = arc->center.y - arc->point[0].y;
  33.     alpha = atan2(dy, dx);
  34.     if (alpha < 0.0) alpha += Three_sixty_deg;
  35.     /* compute_angle returns value between 0 to 2PI */
  36.     
  37.     radius = sqrt((double)(dx * dx + dy * dy));
  38.  
  39.     dx = arc->point[2].x - arc->center.x;
  40.     dy = arc->center.y - arc->point[2].y;
  41.     beta = atan2(dy, dx);
  42.     if (beta < 0.0) beta += Three_sixty_deg;
  43.  
  44.     bx = max(arc->point[0].x, arc->point[1].x);
  45.     bx = max(arc->point[2].x, bx);
  46.     by = max(arc->point[0].y, arc->point[1].y);
  47.     by = max(arc->point[2].y, by);
  48.     sx = min(arc->point[0].x, arc->point[1].x);
  49.     sx = min(arc->point[2].x, sx);
  50.     sy = min(arc->point[0].y, arc->point[1].y);
  51.     sy = min(arc->point[2].y, sy);
  52.  
  53.     if (arc->direction == 1) { /* counter clockwise */
  54.         if (alpha > beta) {
  55.         if (alpha <= 0 || 0 <= beta)
  56.             bx = (int)(arc->center.x + radius + 1.0);
  57.         if (alpha <= Ninety_deg || Ninety_deg <= beta)
  58.             sy = (int)(arc->center.y - radius - 1.0);
  59.         if (alpha <= One_eighty_deg || One_eighty_deg <= beta)
  60.             sx = (int)(arc->center.x - radius - 1.0);
  61.         if (alpha <= Two_seventy_deg || Two_seventy_deg <= beta)
  62.             by = (int)(arc->center.y + radius + 1.0);
  63.         }
  64.         else {
  65.         if (0 <= beta && alpha <= 0)
  66.             bx = (int)(arc->center.x + radius + 1.0);
  67.         if (Ninety_deg <= beta && alpha <= Ninety_deg)
  68.             sy = (int)(arc->center.y - radius - 1.0);
  69.         if (One_eighty_deg <= beta && alpha <= One_eighty_deg)
  70.             sx = (int)(arc->center.x - radius - 1.0);
  71.         if (Two_seventy_deg <= beta && alpha <= Two_seventy_deg)
  72.             by = (int)(arc->center.y + radius + 1.0);
  73.         }
  74.         }
  75.     else {    /* clockwise    */
  76.         if (alpha > beta) {
  77.         if (beta <= 0 && 0 <= alpha)
  78.             bx = (int)(arc->center.x + radius + 1.0);
  79.         if (beta <= Ninety_deg && Ninety_deg <= alpha)
  80.             sy = (int)(arc->center.y - radius - 1.0);
  81.         if (beta <= One_eighty_deg && One_eighty_deg <= alpha)
  82.             sx = (int)(arc->center.x - radius - 1.0);
  83.         if (beta <= Two_seventy_deg && Two_seventy_deg <= alpha)
  84.             by = (int)(arc->center.y + radius + 1.0);
  85.         }
  86.         else {
  87.         if (0 <= alpha || beta <= 0)
  88.             bx = (int)(arc->center.x + radius + 1.0);
  89.         if (Ninety_deg <= alpha || beta <= Ninety_deg)
  90.             sy = (int)(arc->center.y - radius - 1.0);
  91.         if (One_eighty_deg <= alpha || beta <= One_eighty_deg)
  92.             sx = (int)(arc->center.x - radius - 1.0);
  93.         if (Two_seventy_deg <= alpha || beta <= Two_seventy_deg)
  94.             by = (int)(arc->center.y + radius + 1.0);
  95.         }
  96.         }
  97.     *xmax = bx; *ymax = by;
  98.     *xmin = sx; *ymin = sy;
  99.     }
  100.  
  101. compound_bound(compound, xmin, ymin, xmax, ymax)
  102. F_compound    *compound;
  103. int        *xmin, *ymin, *xmax, *ymax;
  104. {
  105.     F_arc        *a;
  106.     F_ellipse    *e;
  107.     F_compound    *c;
  108.     F_spline    *s;
  109.     F_line        *l;
  110.     F_text        *t;
  111.     int        bx, by, sx, sy, first = 1;
  112.     int        llx, lly, urx, ury;
  113.  
  114.     for (a = compound->arcs; a != NULL; a = a->next) {
  115.         arc_bound(a, &sx, &sy, &bx, &by);
  116.         if (first) {
  117.         first = 0;
  118.         llx = sx; lly = sy;
  119.         urx = bx; ury = by;
  120.         }
  121.         else {
  122.         llx = min(llx, sx); lly = min(lly, sy);
  123.         urx = max(urx, bx); ury = max(ury, by);
  124.         }
  125.         }
  126.  
  127.     for (c = compound->compounds; c != NULL; c = c->next) {
  128.         compound_bound(c, &sx, &sy, &bx, &by);
  129.         if (first) {
  130.         first = 0;
  131.         llx = sx; lly = sy;
  132.         urx = bx; ury = by;
  133.         }
  134.         else {
  135.         llx = min(llx, sx); lly = min(lly, sy);
  136.         urx = max(urx, bx); ury = max(ury, by);
  137.         }
  138.         }
  139.  
  140.     for (e = compound->ellipses; e != NULL; e = e->next) {
  141.         ellipse_bound(e, &sx, &sy, &bx, &by);
  142.         if (first) {
  143.         first = 0;
  144.         llx = sx; lly = sy;
  145.         urx = bx; ury = by;
  146.         }
  147.         else {
  148.         llx = min(llx, sx); lly = min(lly, sy);
  149.         urx = max(urx, bx); ury = max(ury, by);
  150.         }
  151.         }
  152.  
  153.     for (l = compound->lines; l != NULL; l = l->next) {
  154.         line_bound(l, &sx, &sy, &bx, &by);
  155.         if (first) {
  156.         first = 0;
  157.         llx = sx; lly = sy;
  158.         urx = bx; ury = by;
  159.         }
  160.         else {
  161.         llx = min(llx, sx); lly = min(lly, sy);
  162.         urx = max(urx, bx); ury = max(ury, by);
  163.         }
  164.         }
  165.  
  166.     for (s = compound->splines; s != NULL; s = s->next) {
  167.         spline_bound(s, &sx, &sy, &bx, &by);
  168.         if (first) {
  169.         first = 0;
  170.         llx = sx; lly = sy;
  171.         urx = bx; ury = by;
  172.         }
  173.         else {
  174.         llx = min(llx, sx); lly = min(lly, sy);
  175.         urx = max(urx, bx); ury = max(ury, by);
  176.         }
  177.         }
  178.  
  179.     for (t = compound->texts; t != NULL; t = t->next) {
  180.         text_bound(t, &sx, &sy, &bx, &by);
  181.         if (first) {
  182.         first = 0;
  183.         llx = sx; lly = sy;
  184.         urx = bx; ury = by;
  185.         }
  186.         else {
  187.         llx = min(llx, sx); lly = min(lly, sy);
  188.         urx = max(urx, bx); ury = max(ury, by);
  189.         }
  190.         }
  191.  
  192.     *xmin = llx; *ymin = lly;
  193.     *xmax = urx; *ymax = ury;
  194.     }
  195.  
  196. ellipse_bound(e, xmin, ymin, xmax, ymax)
  197. F_ellipse    *e;
  198. int        *xmin, *ymin, *xmax, *ymax;
  199. {
  200.     *xmin = e->center.x - e->radiuses.x;
  201.     *ymin = e->center.y - e->radiuses.y;
  202.     *xmax = e->center.x + e->radiuses.x;
  203.     *ymax = e->center.y + e->radiuses.y;
  204.     }
  205.  
  206. line_bound(l, xmin, ymin, xmax, ymax)
  207. F_line    *l;
  208. int    *xmin, *ymin, *xmax, *ymax;
  209. {
  210.     points_bound(l->points, xmin, ymin, xmax, ymax);
  211.     }
  212.  
  213. spline_bound(s, xmin, ymin, xmax, ymax)
  214. F_spline    *s;
  215. int        *xmin, *ymin, *xmax, *ymax;
  216. {
  217.     if (int_spline(s)) {
  218.         int_spline_bound(s, xmin, ymin, xmax, ymax);
  219.         }
  220.     else {
  221.         normal_spline_bound(s, xmin, ymin, xmax, ymax);
  222.         }
  223.     }
  224.  
  225. int_spline_bound(s, xmin, ymin, xmax, ymax)
  226. F_spline    *s;
  227. int        *xmin, *ymin, *xmax, *ymax;
  228. {
  229.     F_point        *p1, *p2;
  230.     F_control    *cp1, *cp2;
  231.     float        x0, y0, x1, y1, x2, y2, x3, y3, sx1, sy1, sx2, sy2;
  232.     float        tx, ty, tx1, ty1, tx2, ty2;
  233.     float        sx, sy, bx, by;
  234.  
  235.     p1 = s->points;
  236.     sx = bx = p1->x;
  237.     sy = by = p1->y;
  238.     cp1 = s->controls;
  239.     for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
  240.         p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
  241.         x0 = p1->x; y0 = p1->y;
  242.         x1 = cp1->rx; y1 = cp1->ry;
  243.         x2 = cp2->lx; y2 = cp2->ly;
  244.         x3 = p2->x; y3 = p2->y;
  245.         tx = half(x1, x2); ty = half(y1, y2);
  246.         sx1 = half(x0, x1); sy1 = half(y0, y1);
  247.         sx2 = half(sx1, tx); sy2 = half(sy1, ty);
  248.         tx2 = half(x2, x3); ty2 = half(y2, y3);
  249.         tx1 = half(tx2, tx); ty1 = half(ty2, ty);
  250.  
  251.         sx = min(x0, sx); sy = min(y0, sy);
  252.         sx = min(sx1, sx); sy = min(sy1, sy);
  253.         sx = min(sx2, sx); sy = min(sy2, sy);
  254.         sx = min(tx1, sx); sy = min(ty1, sy);
  255.         sx = min(tx2, sx); sy = min(ty2, sy);
  256.         sx = min(x3, sx); sy = min(y3, sy);
  257.  
  258.         bx = max(x0, bx); by = max(y0, by);
  259.         bx = max(sx1, bx); by = max(sy1, by);
  260.         bx = max(sx2, bx); by = max(sy2, by);
  261.         bx = max(tx1, bx); by = max(ty1, by);
  262.         bx = max(tx2, bx); by = max(ty2, by);
  263.         bx = max(x3, bx); by = max(y3, by);
  264.         }
  265.     *xmin = round(sx);
  266.     *ymin = round(sy);
  267.     *xmax = round(bx);
  268.     *ymax = round(by);
  269.     }
  270.  
  271. normal_spline_bound(s, xmin, ymin, xmax, ymax)
  272. F_spline    *s;
  273. int        *xmin, *ymin, *xmax, *ymax;
  274. {
  275.     F_point    *p;
  276.     float    cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  277.     float    x1, y1, x2, y2, sx, sy, bx, by;
  278.     float    px, py, qx, qy;
  279.  
  280.     p = s->points;
  281.     x1 = p->x;  y1 = p->y;
  282.     p = p->next;
  283.     x2 = p->x;  y2 = p->y;
  284.     cx1 = (x1 + x2) / 2.0;   cy1 = (y1 + y2) / 2.0;
  285.     cx2 = (cx1 + x2) / 2.0;  cy2 = (cy1 + y2) / 2.0;
  286.     if (closed_spline(s)) {
  287.         x1 = (cx1 + x1) / 2.0;
  288.         y1 = (cy1 + y1) / 2.0;
  289.         }
  290.     sx = min(x1, cx2); sy = min(y1, cy2);
  291.     bx = max(x1, cx2); by = max(y1, cy2);
  292.  
  293.     for (p = p->next; p != NULL; p = p->next) {
  294.         x1 = x2;  y1 = y2;
  295.         x2 = p->x;  y2 = p->y;
  296.         cx4 = (x1 + x2) / 2.0; cy4 = (y1 + y2) / 2.0;
  297.         cx3 = (x1 + cx4) / 2.0; cy3 = (y1 + cy4) / 2.0;
  298.         cx2 = (cx4 + x2) / 2.0;  cy2 = (cy4 + y2) / 2.0;
  299.  
  300.         px = min(cx2, cx3); py = min(cy2, cy3);
  301.         qx = max(cx2, cx3); qy = max(cy2, cy3);
  302.  
  303.         sx = min(sx, px); sy = min(sy, py);
  304.         bx = max(bx, qx); by = max(by, qy);
  305.         }
  306.     if (closed_spline(s)) {
  307.         *xmin = round(sx); *ymin = round(sy);
  308.         *xmax = round(bx); *ymax = round(by);
  309.         }
  310.     else {
  311.         *xmin = round(min(sx, x2)); *ymin = round(min(sy, y2));
  312.         *xmax = round(max(bx, x2)); *ymax = round(max(by, y2));
  313.         }
  314.     }
  315.  
  316. text_bound(t, xmin, ymin, xmax, ymax)
  317. F_text    *t;
  318. int    *xmin, *ymin, *xmax, *ymax;
  319. {
  320.     *xmin = t->base_x;
  321.     *ymin = t->base_y - t->height;
  322.     *xmax = t->base_x + t->length;
  323.     *ymax = t->base_y;
  324.     }
  325.  
  326. points_bound(points, xmin, ymin, xmax, ymax)
  327. F_point    *points;
  328. int    *xmin, *ymin, *xmax, *ymax;
  329. {
  330.     int    bx, by, sx, sy;
  331.     F_point    *p;
  332.  
  333.     bx = sx = points->x; by = sy = points->y;
  334.     for (p = points->next; p != NULL; p = p->next) {
  335.         sx = min(sx, p->x); sy = min(sy, p->y);
  336.         bx = max(bx, p->x); by = max(by, p->y);
  337.         }
  338.     *xmin = sx; *ymin = sy;
  339.     *xmax = bx; *ymax = by;
  340.     }
  341.  
  342. control_points_bound(cps, xmin, ymin, xmax, ymax)
  343. F_control    *cps;
  344. int        *xmin, *ymin, *xmax, *ymax;
  345. {
  346.     F_control    *c;
  347.     float        bx, by, sx, sy;
  348.  
  349.     bx = sx = cps->lx;
  350.     by = sy = cps->ly;
  351.     sx = min(sx, cps->rx); sy = min(sy, cps->ry);
  352.     bx = max(bx, cps->rx); by = max(by, cps->ry);
  353.     for (c = cps->next; c != NULL; c = c->next) {
  354.         sx = min(sx, c->lx); sy = min(sy, c->ly);
  355.         bx = max(bx, c->lx); by = max(by, c->ly);
  356.         sx = min(sx, c->rx); sy = min(sy, c->ry);
  357.         bx = max(bx, c->rx); by = max(by, c->ry);
  358.         }
  359.     *xmin = round(sx); *ymin = round(sy);
  360.     *xmax = round(bx); *ymax = round(by);
  361.     }
  362.